package com.nanhai.buddhist.college.module.collegebase.service.teacherteachers;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.nanhai.buddhist.college.module.collegebase.api.student.vo.UpdatePasswordVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.teacherteachers.vo.TeacherTeachersCreateReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.teacherteachers.vo.TeacherTeachersExportReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.teacherteachers.vo.TeacherTeachersPageReqVO;
import com.nanhai.buddhist.college.module.collegebase.controller.admin.teacherteachers.vo.TeacherTeachersUpdateReqVO;
import com.nanhai.buddhist.college.module.collegebase.convert.teacherteachers.TeacherTeachersConvert;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.classes.ClassesDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.classes.ClassesInfoDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.classes.ClassesTeacherDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.colleges.CollegesDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.departments.DepartmentsDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.professions.ProfessionsDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.studentroll.StudentRollDO;
import com.nanhai.buddhist.college.module.collegebase.dal.dataobject.teacherteachers.TeacherTeachersDO;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.classes.ClassesMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.classes.ClassesTeacherMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.colleges.CollegesMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.departments.DepartmentsMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.professions.ProfessionsMapper;
import com.nanhai.buddhist.college.module.collegebase.dal.mysql.teacherteachers.TeacherTeachersMapper;
import com.nanhai.buddhist.college.module.collegebase.enums.ClassesTeacherTypeEnum;
import com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants;
import com.nanhai.buddhist.college.module.system.api.user.AdminUserApi;
import com.nanhai.buddhist.college.module.system.api.user.dto.TeacherUserCreatedReqDTO;
import com.nanhai.buddhist.college.module.system.api.user.dto.TeacherUserUpdatedReqDTO;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants.IDENTITY_CARD_NUMBER_HAVE_EXISTS;
import static com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants.JOB_NUMBER_HAVE_EXISTS;
import static com.nanhai.buddhist.college.module.collegebase.enums.ErrorCodeConstants.TEACHER_USER_ADD_EXISTS;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 教师管理 Service 实现类
 *
 * @author AKai
 */
@Service
@Validated
public class TeacherTeachersServiceImpl implements TeacherTeachersService {

    @Resource
    private TeacherTeachersMapper teacherTeachersMapper;

    @Resource
    private ClassesTeacherMapper classesTeacherMapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private CollegesMapper collegesMapper;

    @Resource
    private ClassesMapper classesMapper;

    @Resource
    private AdminUserApi adminUserApi;

    @Override
    @Transactional
    public String createTeacherTeachers(TeacherTeachersCreateReqVO createReqVO) {
        // 插入
        TeacherTeachersDO teacherTeachers = TeacherTeachersConvert.INSTANCE.convert(createReqVO);
        // 检验 工号 和 身份证 的唯一
        checkIdAndNumber(teacherTeachers);

        String password = "123456";
        final String substring = StringUtils.substring(teacherTeachers.getIdentityCardNumber(), -6);
        if (StringUtils.isNotBlank(substring)) {
            password = substring;
        }
        String encode = passwordEncoder.encode(password);
        teacherTeachers.setPassword(encode);

        // 插入教师用户
        final String userId = createdTeacherUser(createReqVO, encode);

        // 插入用户信息
        teacherTeachers.setUserId(userId);
        teacherTeachersMapper.insert(teacherTeachers);
        // 返回
        return teacherTeachers.getId();
    }

    @NotNull
    private String createdTeacherUser(TeacherTeachersCreateReqVO createReqVO, String encode) {
        TeacherUserCreatedReqDTO createdReqDTO = new TeacherUserCreatedReqDTO();
        createdReqDTO.setAge(Integer.parseInt(createReqVO.getTeacherAge()));
        createdReqDTO.setAvatar(createReqVO.getHeadImage());
        createdReqDTO.setCardId(createReqVO.getIdentityCardNumber());
        HashSet<String> collegeSet = new HashSet<>();
        collegeSet.add(createReqVO.getCollegeId());
        createdReqDTO.setCollegeIds(collegeSet);
        // createdReqDTO.setEmail()
        createdReqDTO.setMobile(createReqVO.getTeacherTelephone());
        createdReqDTO.setNickname(createReqVO.getTeacherName());
        createdReqDTO.setPostName("教师");
        createdReqDTO.setPassword(encode);
        createdReqDTO.setSex(Integer.parseInt(createReqVO.getTeacherSex()));
        createdReqDTO.setRemark(createReqVO.getRemark());
        createdReqDTO.setUsername(createReqVO.getJobNumber());
        // 0是开启状态
        createdReqDTO.setStatus(0);
        final String userId = adminUserApi.teacherUserCreated(createdReqDTO).getData();
        if (StringUtils.isBlank(userId)) {
            throw exception(TEACHER_USER_ADD_EXISTS);
        }
        return userId;
    }

    private void checkIdAndNumber(TeacherTeachersDO teacherTeachers) {
        Long idCount = teacherTeachersMapper.selectCount(new LambdaQueryWrapper<TeacherTeachersDO>()
                .eq(TeacherTeachersDO::getIdentityCardNumber, teacherTeachers.getIdentityCardNumber()));
        if (ObjectUtil.isNotNull(idCount) && idCount > 0) {
            throw exception(IDENTITY_CARD_NUMBER_HAVE_EXISTS);
        }

        Long numberCount = teacherTeachersMapper.selectCount(new LambdaQueryWrapper<TeacherTeachersDO>()
                .eq(TeacherTeachersDO::getJobNumber, teacherTeachers.getJobNumber()));
        if (ObjectUtil.isNotNull(numberCount) && numberCount > 0) {
            throw exception(JOB_NUMBER_HAVE_EXISTS);
        }
    }


    private void updatedCheckIdAndNumber(TeacherTeachersDO teacherTeachers) {
        Long idCount = teacherTeachersMapper.selectCount(new LambdaQueryWrapper<TeacherTeachersDO>()
                .eq(TeacherTeachersDO::getIdentityCardNumber, teacherTeachers.getIdentityCardNumber())
                .ne(TeacherTeachersDO::getId, teacherTeachers.getId()));
        if (ObjectUtil.isNotNull(idCount) && idCount > 0) {
            throw exception(IDENTITY_CARD_NUMBER_HAVE_EXISTS);
        }

        Long numberCount = teacherTeachersMapper.selectCount(new LambdaQueryWrapper<TeacherTeachersDO>()
                .eq(TeacherTeachersDO::getJobNumber, teacherTeachers.getJobNumber())
                .ne(TeacherTeachersDO::getId, teacherTeachers.getId()));
        if (ObjectUtil.isNotNull(numberCount) && numberCount > 0) {
            throw exception(JOB_NUMBER_HAVE_EXISTS);
        }
    }

    @Override
    public void updateTeacherTeachers(TeacherTeachersUpdateReqVO updateReqVO) {
        // 校验存在
        TeacherTeachersDO teacherTeachersDO = teacherTeachersMapper.selectById(updateReqVO.getId());
        if (teacherTeachersDO == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TEACHER_TEACHERS_NOT_EXISTS);
        }

        // 更新
        TeacherTeachersDO updateObj = TeacherTeachersConvert.INSTANCE.convert(updateReqVO);
        // 检验 工号 和 身份证 的唯一
        updatedCheckIdAndNumber(updateObj);
        teacherTeachersMapper.updateById(updateObj);
        // 更新用戶信息
        updateTeacherUser(updateReqVO, teacherTeachersDO);
        // 如果更换了学院需要删除教师所在学院的 班级绑定
        deletedClassesBind(updateReqVO, teacherTeachersDO);

    }

    private void updateTeacherUser(TeacherTeachersUpdateReqVO updateReqVO, TeacherTeachersDO updateObj) {
        TeacherUserUpdatedReqDTO updatedReqDTO = new TeacherUserUpdatedReqDTO();
        updatedReqDTO.setAge(Integer.parseInt(updateReqVO.getTeacherAge()));
        updatedReqDTO.setAvatar(updateReqVO.getHeadImage());
        updatedReqDTO.setCardId(updateReqVO.getIdentityCardNumber());
        HashSet<String> collegeSet = new HashSet<>();
        collegeSet.add(updateReqVO.getCollegeId());
        updatedReqDTO.setMobile(updateReqVO.getTeacherTelephone());
        updatedReqDTO.setCollegeIds(collegeSet);
        updatedReqDTO.setNickname(updateReqVO.getTeacherName());
        updatedReqDTO.setSex(Integer.parseInt(updateReqVO.getTeacherSex()));
        updatedReqDTO.setRemark(updateReqVO.getRemark());
        updatedReqDTO.setUsername(updateReqVO.getJobNumber());
        updatedReqDTO.setUserId(updateObj.getUserId());
        adminUserApi.teacherUserUpdated(updatedReqDTO);
    }

    private void deletedClassesBind(TeacherTeachersUpdateReqVO updateReqVO, TeacherTeachersDO teacherTeachersDO) {
        if (updateReqVO.getCollegeId().equals(teacherTeachersDO.getCollegeId())) {
            return;
        }

        List<String> arrayList = new ArrayList<>();
        arrayList.add(teacherTeachersDO.getCollegeId());
        List<ClassesInfoDO> classesInfoDOS = collegesMapper.selectClassesIdByCollege(arrayList);
        if (CollectionUtil.isNotEmpty(classesInfoDOS)) {
            List<String> collect = classesInfoDOS.stream().map(ClassesInfoDO::getClassesId).collect(Collectors.toList());
            classesTeacherMapper.delete(new LambdaQueryWrapper<ClassesTeacherDO>()
                    .in(ClassesTeacherDO::getClassesId, collect)
                    .eq(ClassesTeacherDO::getTeacherId, updateReqVO.getId()));
        }

    }

    @Override
    public void deleteTeacherTeachers(String id) {
        // 校验存在
        this.validateTeacherTeachersExists(id);
        // 删除
        teacherTeachersMapper.deleteById(id);
    }

    private void validateTeacherTeachersExists(String id) {
        if (teacherTeachersMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.TEACHER_TEACHERS_NOT_EXISTS);
        }
    }


    @Override
    public TeacherTeachersDO getTeacherTeachers(String id) {
        TeacherTeachersDO teacherTeachersDO = teacherTeachersMapper.selectById(id);

        if (ObjectUtil.isNull(teacherTeachersDO)) {
            return null;
        }
        CollegesDO collegesDO = collegesMapper.selectById(teacherTeachersDO.getCollegeId());
        if (ObjectUtil.isNotNull(teacherTeachersDO)) {
            teacherTeachersDO.setCollegeName(collegesDO.getCollegeName());
        }
        return teacherTeachersDO;
    }

    @Override
    public List<TeacherTeachersDO> getTeacherTeachersList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : teacherTeachersMapper.selectBatchIdsJoin(ids);
    }

    @Override
    public PageResult<TeacherTeachersDO> getTeacherTeachersPage(TeacherTeachersPageReqVO pageReqVO) {
        return teacherTeachersMapper.selectPage(pageReqVO);
    }

    @Override
    public List<TeacherTeachersDO> getTeacherTeachersList(TeacherTeachersExportReqVO exportReqVO) {
        return teacherTeachersMapper.selectList(exportReqVO);
    }


    @Override
    public TeacherTeachersDO getUserByUsername(String username) {
        return teacherTeachersMapper.getUserByUsername(username);
    }

    @Override
    public List<TeacherTeachersDO> getTeacherListByClassesId(String id) {
        final ClassesDO classesDO = classesMapper.selectById(id);
        if (ObjectUtil.isNull(classesDO)) {
            return new ArrayList<TeacherTeachersDO>();
        }
        List<ClassesTeacherDO> list = classesTeacherMapper.selectList(new LambdaQueryWrapper<ClassesTeacherDO>()
                .eq(ClassesTeacherDO::getClassesId, id)
                .eq(ClassesTeacherDO::getTeacherUserType, classesDO.getTeacherUserType()));
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<TeacherTeachersDO>();
        }
        List<TeacherTeachersDO> resList = new ArrayList<>(list.size());
        list.forEach(item -> {
            TeacherTeachersDO aDo = teacherTeachersMapper.selectById(item.getTeacherId());
            aDo.setTeacherUserType(item.getTeacherUserType());
            resList.add(aDo);
        });
        return resList;
    }

    @Override
    public List<TeacherTeachersDO> getTeacherTeachersDOListByStr(String findStr) {
        LambdaQueryWrapper<TeacherTeachersDO> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(findStr)) {
            wrapper.like(TeacherTeachersDO::getTeacherName, findStr)
                    .or().like(TeacherTeachersDO::getJobNumber, findStr)
                    .or().like(TeacherTeachersDO::getLegalName, findStr);
        }
        return teacherTeachersMapper.selectList(wrapper);
    }


    @Override
    public List<TeacherTeachersDO> getByCollegeId(String collegeId) {
        LambdaQueryWrapperX<TeacherTeachersDO> teacherTeachersDOLambdaQueryWrapperX = new LambdaQueryWrapperX<TeacherTeachersDO>().eqIfPresent(TeacherTeachersDO::getCollegeId, collegeId);
        return teacherTeachersMapper.selectList(teacherTeachersDOLambdaQueryWrapperX);
    }


    @Override
    @Transactional
    public void updatedStudentPassword(UpdatePasswordVO req) {
        TeacherTeachersDO teacherTeachersDO = teacherTeachersMapper.selectById(req.getId());
        if (ObjectUtil.isEmpty(teacherTeachersDO)) {
            throw exception(ErrorCodeConstants.SELECT_NULL_ERROR);
        }
        String encode = passwordEncoder.encode(req.getPassWord());
        teacherTeachersDO.setPassword(encode);
        teacherTeachersMapper.updateById(teacherTeachersDO);

        // 同步修改用户表的密码
        TeacherUserUpdatedReqDTO updatedReqDTO = new TeacherUserUpdatedReqDTO();
        updatedReqDTO.setUserId(teacherTeachersDO.getUserId());
        updatedReqDTO.setPassword(encode);
        adminUserApi.teacherUserUpdated(updatedReqDTO);


    }

    @Override
    public List<TeacherTeachersDO> getAllTeacherList() {
        return teacherTeachersMapper.selectList();
    }

    /*@Override
    public Set<String> getAdminUserId(String id) {
        final List<ClassesTeacherDO> classesTeacherDOS = classesTeacherMapper.selectList(new LambdaQueryWrapper<ClassesTeacherDO>().eq(ClassesTeacherDO::getTeacherId, id));
        Set<String> resSet = new HashSet<>();
        if (CollectionUtil.isEmpty(classesTeacherDOS)) {
            return resSet;
        }
        classesTeacherDOS.forEach(item -> {

            ClassesDO classesDO = classesMapper.selectById(item.getClassesId());
            if (ObjectUtil.isNull(classesDO)) {
                return;
            }

            // 获取专业用户id
            ProfessionsDO professionsDO = professionsMapper.selectById(classesDO.getProfessionId());
            if (ObjectUtil.isNull(professionsDO)) {
                return;
            }
            resSet.add(professionsDO.getUserId());

            // 获取系部用户id
            DepartmentsDO departmentsDO = departmentsMapper.selectById(professionsDO.getDepartmentsId());
            if (ObjectUtil.isNull(departmentsDO)) {
                return;
            }
            resSet.add(departmentsDO.getUserId());

            // 获取学院用户id
            CollegesDO collegesDO = collegesMapper.selectById(departmentsDO.getCollegeId());
            if (ObjectUtil.isNull(collegesDO)) {
                return;
            }
            resSet.add(collegesDO.getUserId());

        });

        return resSet;
    }*/

}
